<template>
  <basic-container v-loading="loading" element-loading-text="数据加载中...">
    <dataList
      ref="roleCrud"
      hideFilterBtn
      openIndex
      operaColumnWidth="130"
      :pageInfo="pager"
      :listData="tableData"
      :dataInfo="dataInfo"
      :operaInfo="operaInfo"
      :menuList="menuList"
      :listLayout="['menu','filter']"
      :filterList="filterList"
      @btn-click="handleBtnClick"
      @menu-click="handleMenuClick"
    ></dataList>
    <v-dialog :show.sync="dialogPermissionVisible" :lock-scroll="false" title="分配权限">
      <div class="dialog-main-tree">
        <el-tree
          ref="menuTree"
          :data="treeData"
          :default-checked-keys="checkedKeys"
          :check-strictly="false"
          :props="defaultProps"
          :filter-node-method="filterNode"
          class="filter-tree"
          node-key="id"
          highlight-current
          show-checkbox
          default-expand-all
        />
      </div>
      <div slot="foot" class="dialog-footer">
        <el-button type="primary" size="small" @click="updatePermession(roleId)">更 新</el-button>
        <el-button type="default" size="small" @click="cancal()">取消</el-button>
      </div>
    </v-dialog>
    <v-dialog
      :title="isLook ? '查看' : (isEdit ? '编辑' : '新增')"
      :show.sync="dialogVisible"
      class="dialogForm"
      width="1000px"
      v-loading="dialogLoading"
      @beforeClose="beforeClose"
      element-loading-text="正在保存..."
      v-if="dialogVisible"
    >
      <el-form ref="tableOptionForm" class="form-wrap" :rules="tableOption_rules" :model="tableOption" label-width="80px" label-position="left">
        <el-form-item label="角色名称" :prop="isLook ? '' : 'roleName'">
          <el-input v-halfCharCode maxlength="20" minlength="3" placeholder="请输入角色名称" v-model="tableOption.roleName" v-if="!isLook" />
          <span class="in_txt" v-if="isLook">{{tableOption.roleName}}</span>
        </el-form-item>
        <el-form-item label="角色标识" :prop="isLook ? '' : 'roleCode'">
          <el-input
            v-halfCharCode
            type="text"
            maxlength="20"
            minlength="3"
            placeholder="请输入角色标识"
            v-model="tableOption.roleCode"
            :disabled="isEdit"
            v-if="!isLook"
          />
          <span class="in_txt" v-if="isLook">{{tableOption.roleCode}}</span>
        </el-form-item>
        <el-form-item label="角色描述" :prop="isLook ? '' : 'roleDesc'">
          <el-input v-halfCharCode maxlength="100" placeholder="请输入角色描述" v-model="tableOption.roleDesc" v-if="!isLook" />
          <span class="in_txt" v-if="isLook">{{tableOption.roleDesc}}</span>
        </el-form-item>
        <el-form-item label="创建时间" prop="createTime" v-if="isLook">
          <span class="in_txt" v-if="isLook">{{tableOption.createTime}}</span>
        </el-form-item>
      </el-form>
      <span slot="foot" v-if="!isLook">
        <el-button v-throttle="[commit]">{{isEdit ? '修 改' : '保 存'}}</el-button>
        <el-button @click="handleCancel">取 消</el-button>
      </span>
    </v-dialog>
  </basic-container>
</template>

<script>
import { addObj, delObj, fetchList, fetchRoleTree, permissionUpd, putObj } from '@/admin/api/role'
import { fetchMenuTree } from '@/admin/api/menu'
export default {
  name: "TableRole",
  provide () {
    return {
      initList: this.getListData
    };
  },
  beforeMount () {
    this.getListData()
  },
  data () {
    return {
      tableData: [],
      // 请求参数
      params: {
        current: 1,
        size: 10
      },
      // 分页
      pager: {
        total: 0, // 总页数
        current: 1, // 当前页数
        size: 10 // 每页显示多少条
      },
      filterList: [
        { label: '角色名称', inputType: 'input', name: 'roleName', placeholder: '请输入角色名称', defaultValue: '' },
        { label: '角色描述', inputType: 'input', name: 'roleDesc', placeholder: '请输入角色描述', defaultValue: '' },
      ],
      // 页面loading
      loading: false,
      // 权限弹框
      dialogPermissionVisible: false,
      treeData: [],
      checkedKeys: [],
      defaultProps: {
        label: 'name',
        value: 'id'
      },
      // 新增、编辑、查看弹框
      isEdit: false,
      isLook: false,
      dialogLoading: false,
      dialogVisible: false,
      tableOption: {
        roleName: '',
        roleCode: '',
        roleDesc: '',
        createTime: ''
      },
      tableOption_rules: {
        roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' },
        { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }],
        roleCode: [{ required: true, message: '角色标识不能为空', trigger: 'blur' },
        { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }],
        roleDesc: [{ required: true, message: '角色描述不能为空', trigger: 'blur' },
        { max: 100, message: '角色描述长度不大于100个字符', trigger: 'blur' }]
      }
    }
  },
  computed: {
    //顶部菜单
    menuList () {
      return this.getPermissions('sys_role_add') ? [{ add: '添加' }] : []
    },
    // 权限配置
    permissionList () {
      return {
        editBtn: this.getPermissions('sys_role_edit'),
        delBtn: this.getPermissions('sys_role_del'),
        permBtn: this.getPermissions('sys_role_perm')
      }
    },
    // 配置表头
    dataInfo () {
      return [
        { label: '角色名称', prop: 'roleName', width: '280', 'show-overflow-tooltip': true  },
        { label: '角色标识', prop: 'roleCode', width: '280', 'show-overflow-tooltip': true },
        { label: '角色描述', prop: 'roleDesc', width: '280', 'show-overflow-tooltip': true },
        { label: '创建时间', prop: 'createTime', width: '280' }
      ]
    },
    // 操作项配置
    operaInfo () {
      return [
        { label: '编辑', name: 'edit', verify: () => this.permissionList.editBtn },
        { label: '删除', name: 'delete', verify: () => this.permissionList.delBtn },
        { label: '权限', name: 'permission', verify: () => this.permissionList.permBtn },
      ]
    }
  },
  methods: {
    // 获取列表
    getListData (params = {}) {
      this.loading = true;
      let requestData = { ...this.params, ...params };
      fetchList(requestData)
        .then(res => {
          const { current, size, total, records } = res.data.data;
          this.tableData = records;
          this.params = requestData;
          this.pager = { total, current, size };
        })
        .finally(() => {
          this.loading = false;
        });
    },
    // 菜单点击监听
    handleMenuClick (type) {
      switch (type) {
        case "add":
          this.handleCreate();
          break;
        default:
          this.$message(type);
          break;
      }
    },
    // 按钮点击监听
    handleBtnClick ({ type, row }) {
      switch (type) {
        case 'edit':
          this.handleUpdate(row)
          break;
        case 'delete':
          this.handleDelete(row)
          break;
        case 'permission':
          this.handlePermission(row)
          break;
        default:
          break;
      }
    },
    // 查看
    handleLook (row) {
      this.tableOption = row
      this.isLook = true
      this.dialogVisible = true
    },
    // 编辑
    handleUpdate (row) {
      this.tableOption = row
      this.isEdit = true
      this.dialogVisible = true
    },
    // 删除
    handleDelete (row) {
      this.$confirm('是否确认删除名称为"' + row.roleName + '"' + '"的数据项?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(function () {
        return delObj(row.roleId)
      }).then(() => {
        this.getListData({ current: 1 })
        this.$notify.success('删除成功')
      }).catch(()=>{})
    },
    /**
     * 解析出所有的太监节点id
     * @param json 待解析的json串
     * @param idArr 原始节点数组
     * @param temp 临时存放节点id的数组
     * @return 太监节点id数组
     */
    resolveAllEunuchNodeId (json, idArr, temp) {
      for (let i = 0; i < json.length; i++) {
        const item = json[i]
        // 存在子节点，递归遍历;不存在子节点，将json的id添加到临时数组中
        if (item.children && item.children.length !== 0) {
          this.resolveAllEunuchNodeId(item.children, idArr, temp)
        } else {
          temp.push(idArr.filter(id => id === item.id))
        }
      }
      return temp
    },
    // 权限
    handlePermission (row) {
      fetchRoleTree(row.roleId)
        .then(response => {
          this.checkedKeys = response.data.data
          return fetchMenuTree()
        })
        .then(response => {
          this.treeData = response.data.data
          // 解析出所有的太监节点
          this.checkedKeys = this.resolveAllEunuchNodeId(this.treeData, this.checkedKeys, [])
          this.dialogPermissionVisible = true
          this.roleId = row.roleId
          this.roleCode = row.roleCode
        })
    },
    //权限弹框树结构
    filterNode (value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    //权限更新
    updatePermession (roleId) {
      this.menuIds = ''
      this.menuIds = this.$refs.menuTree.getCheckedKeys().join(',').concat(',').concat(this.$refs.menuTree.getHalfCheckedKeys().join(','))
      permissionUpd(roleId, this.menuIds).then(() => {
        this.dialogPermissionVisible = false
        // this.$store.dispatch('GetMenu', {type:false})
        this.$notify.success('修改成功')
      })
    },
    // 权限取消
    cancal () {
      this.dialogPermissionVisible = false;
    },
    // 弹框保存
    commit () {
      this.$refs.tableOptionForm.validate(valid => {
        if (valid) {
          this.dialogLoading = true
          if (this.isEdit) {
            putObj(this.tableOption).then(res => {
              if (res.data.code === 0) {
                this.$notify.success('修改成功')
                this.dialogLoading = false
                this.handleCancel()
              } else {
                this.$notify.error('修改失败')
                this.dialogLoading = false
                this.handleCancel()
              }
            }).catch(() => {
              this.dialogLoading = false
            })
          } else {
            addObj(this.tableOption).then(res => {
              if (res.data.code === 0) {
                this.$notify.success('创建成功')
                this.dialogLoading = false
                this.handleCancel()
              } else {
                this.$notify.error('创建失败')
                this.dialogLoading = false
                this.handleCancel()
              }
            }).catch(() => {
              this.dialogLoading = false
            })
          }
        }
      })
    },
    // 弹框取消
    handleCancel () {
      Object.keys(this.tableOption).forEach(key => {
        if (this.tableOption[key]) {
          if (this.tableOption[key] instanceof Array) {
            this.tableOption[key] = []
          } else if (typeof this.tableOption[key] === 'string' || typeof this.tableOption[key] === 'number') {
            this.tableOption[key] = ''
          }
        }
      })
      this.dialogVisible = false
      this.isEdit = false
      this.isLook = false
      this.getListData()
    },
    beforeClose (done) {
      this.handleCancel()
    },
    // 新增
    handleCreate () {
      this.dialogVisible = true
    }
  }
}
</script>

<style lang="scss" scoped>
.role {
  @include formWrap(4);
  /deep/ .el-dialog__body {
    height: 70vh;
    overflow: auto;
  }
  .dialogForm {
    @include formWrap(1);
    /deep/ .el-dialog__body {
      height: auto;
    }
  }
}
</style>
